
package JET.Centers.Graphics;

import JET.CenterPanels.CPScene;
import JET.Centers.ControlCenter;
import JET.Exceptions.JETGraphicsException;
import JET.Scene;
import JET.graphics.GraphicPanel;
import JET.graphics.jogl.JoglGraphicPanel;
import JET.graphics.GraphicPanelKeyListener;
import JET.graphics.GraphicPanelMouseListener;
import JET.graphics.GraphicPanelMouseMotionListener;
import JET.graphics.GraphicPanelMouseWheelListener;
import JET.graphics.elements.SceneDrawable;
import JET.graphics.swing.SwingGraphicPanel;
import JET.mygui.CenterTabsPane.CenterTabsPaneTab;
import JET.mygui.MyGuiHelper;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import javax.swing.JPanel;

/**
 *
 * @author 057Ry
 */
public class GraphicsCenter {
    static final ControlCenter CC = ControlCenter.getInstance();

    public boolean needsRepainting = true;
    
    // zmienne strujace trybem rysowania
    private boolean drawMainGrid            = true;
    private boolean drawHelpGrid            = true;
    private boolean drawMainGridXNumbers    = true;
    private boolean drawMainGridYNumbers    = true;
    private boolean drawHelpGridXNumbers    = false;
    private boolean drawHelpGridYNumbers    = false;
    private boolean drawMass2dVelocities    = false;
    private boolean drawMass2dForces        = false;
    private boolean drawMasses2d            = true;
    private boolean drawMass2dIfMoved       = false;
    private boolean drawSprings2d           = true;
    private boolean drawWalls2d             = true;
    private boolean drawMassesNumbers       = false;
    private boolean drawSpringsNumbers      = false;
    private boolean drawWallsNumbers        = false;
    private boolean drawBoundingBoxes       = false;
    private boolean drawSpringBodyCollisions = false;
    private boolean drawSpringBodyGeomCenter = true;
    private boolean drawBorderOrientation   = false;
    private boolean drawActionFrame         = true;

    final private ArrayList<SceneDrawable> drawables = new ArrayList<SceneDrawable>();

    private Scene scene;

    public GraphicsCenter(Scene s) {
        if (s==null) throw new RuntimeException("GC cannot be created with no scene specified!");
        this.scene = s;
    }

    public GraphicPanel getGraphicPanel() {
        CPScene sceneTab = (CPScene) CC.GUIC.getSceneTab(scene.getName());
        if (sceneTab!=null)
            return sceneTab.getGraphicPanel();
        else
            return null;
    }
    
    public Component getJGraphicComponent(String sceneName) {
        CPScene sceneTab = (CPScene) CC.GUIC.getSceneTab(sceneName);
        if (sceneTab!=null)
            return (Component) sceneTab.getGraphicPanel();
        else
            return null;
    }

    public GraphicMode getGraphicMode() {
        CPScene sceneTab = (CPScene) CC.GUIC.getSceneTab(scene.getName());
        if (sceneTab != null)
            return sceneTab.getGraphicMode();
        else
            return GraphicMode.Unknown;
    }
    private GraphicPanel getNewSwingGraphicPanel(String sceneName) {
        SwingGraphicPanel swingGP = new SwingGraphicPanel(sceneName);
        swingGP.addMouseListener(new GraphicPanelMouseListener(swingGP));
        swingGP.addMouseMotionListener(new GraphicPanelMouseMotionListener(swingGP));
        swingGP.addMouseWheelListener(new GraphicPanelMouseWheelListener(swingGP));
        swingGP.addKeyListener(new GraphicPanelKeyListener(swingGP));
        return swingGP;
    }
    public GraphicPanel getNewJoglGraphicPanel(String sceneName) {
        JoglGraphicPanel joglGP = new JoglGraphicPanel(JoglGraphicPanel.createGLCapabilites(), sceneName);
        joglGP.addMouseListener(new GraphicPanelMouseListener((Component) joglGP));
        joglGP.addMouseMotionListener(new GraphicPanelMouseMotionListener((Component) joglGP));
        joglGP.addMouseWheelListener(new GraphicPanelMouseWheelListener(joglGP));
        joglGP.addKeyListener(new GraphicPanelKeyListener(joglGP));
        return joglGP;
    }
    
    public void setGraphicMode(GraphicMode mode) throws JETGraphicsException {
        CenterTabsPaneTab ctpt = CC.GUIC.getSceneTab(scene.getName());
        if (ctpt==null)
            return;

        CPScene sceneTab = (CPScene) ctpt;
        if (sceneTab==null)
            return;

        GraphicPanel gPanel = null;
        switch (mode) {
            case Swing  :
                gPanel = sceneTab.swingGP;
                if (gPanel==null) {
                    try {
                        gPanel = getNewSwingGraphicPanel(scene.getName());
                    } catch(Exception e) { throw new JETGraphicsException("Cannot create swing graphic panel !"); }
                }
                
                sceneTab.setGraphicMode(GraphicMode.Swing);
                sceneTab.swingGP = gPanel;
                sceneTab.gpContainer.removeAll();
                sceneTab.gpContainer.add( MyGuiHelper.getNewJScrollPane((JPanel)gPanel), BorderLayout.CENTER);
                CC.GUIC.reAddGPContainer(sceneTab);
                sceneTab.setGraphicMode(GraphicMode.Swing);
                break;
                
            case OpenGL :
                gPanel = sceneTab.joglGP;
                if (gPanel==null) {
                    try {
                        gPanel = getNewJoglGraphicPanel(scene.getName());
                    } catch(Exception e) { throw new JETGraphicsException("Cannot create jogl graphic panel !"); }
                }

                sceneTab.setGraphicMode(GraphicMode.OpenGL);
                sceneTab.joglGP = gPanel;
                sceneTab.gpContainer.removeAll();
                sceneTab.gpContainer.add((Component)gPanel, BorderLayout.CENTER);
                CC.GUIC.reAddGPContainer(sceneTab);
                sceneTab.setGraphicMode(GraphicMode.OpenGL);
                break;
        }
        
        ((Component)gPanel).setFocusable(true);
        ((Component)gPanel).requestFocus();
    }

    public void setDrawBoundingBoxes(boolean drawBoundingBoxes) {this.drawBoundingBoxes = drawBoundingBoxes;}
    public void setDrawHelpGrid(boolean drawHelpGrid) {this.drawHelpGrid = drawHelpGrid;}
    public void setDrawMainGrid(boolean drawMainGrid) {this.drawMainGrid = drawMainGrid;}
    public void setDrawHelpGridXNumbers(boolean drawHelpGridNumbers) {this.drawHelpGridXNumbers = drawHelpGridNumbers;}
    public void setDrawHelpGridYNumbers(boolean drawHelpGridNumbers) {this.drawHelpGridYNumbers = drawHelpGridNumbers;}
    public void setDrawMainGridXNumbers(boolean drawMainGridNumbers) {this.drawMainGridXNumbers = drawMainGridNumbers;}
    public void setDrawMainGridYNumbers(boolean drawMainGridNumbers) {this.drawMainGridYNumbers = drawMainGridNumbers;}
    public void setDrawMass2dIfMoved(boolean drawMass2dIfMoved) {this.drawMass2dIfMoved = drawMass2dIfMoved;}
    public void setDrawMass2dVelocities(boolean drawMass2dVelocities) {this.drawMass2dVelocities = drawMass2dVelocities;}
    public void setDrawMass2dForces(boolean drawMass2dForces) {this.drawMass2dForces = drawMass2dForces;}
    public void setDrawMasses2d(boolean drawMasses2d) {this.drawMasses2d = drawMasses2d;}
    public void setDrawMassesNumbers(boolean drawMassesNumbers) {this.drawMassesNumbers = drawMassesNumbers;}
    public void setDrawSpringBodyCollisions(boolean drawSpringBodyCollisions) {this.drawSpringBodyCollisions = drawSpringBodyCollisions;}
    public void setDrawSpringBodyGeomCenter(boolean drawSpringBodyGeomCenter) {this.drawSpringBodyGeomCenter = drawSpringBodyGeomCenter;}
    public void setDrawSprings2d(boolean drawSprings2d) {this.drawSprings2d = drawSprings2d;}
    public void setDrawSpringsNumbers(boolean drawSpringsNumbers) {this.drawSpringsNumbers = drawSpringsNumbers;}
    public void setDrawWalls2d(boolean drawWalls2d) {this.drawWalls2d = drawWalls2d;}
    public void setDrawWallsNumbers(boolean drawWallsNumbers) {this.drawWallsNumbers = drawWallsNumbers;}
    public void setDrawBorderOrientation(boolean drawBorderOrientation) {this.drawBorderOrientation = drawBorderOrientation;}
    public void setDrawActionFrame(boolean drawActionFrame) {this.drawActionFrame = drawActionFrame;}
    public boolean isDrawBoundingBoxes() {return drawBoundingBoxes;}
    public boolean isDrawHelpGrid() {return drawHelpGrid;}
    public boolean isDrawMainGrid() {return drawMainGrid;}
    public boolean isDrawHelpGridXNumbers() {return drawHelpGridXNumbers;}
    public boolean isDrawHelpGridYNumbers() {return drawHelpGridYNumbers;}
    public boolean isDrawMainGridXNumbers() {return drawMainGridXNumbers;}
    public boolean isDrawMainGridYNumbers() {return drawMainGridYNumbers;}
    public boolean isDrawMass2dIfMoved() {return drawMass2dIfMoved;}
    public boolean isDrawMass2dVelocities() {return drawMass2dVelocities;}
    public boolean isDrawMass2dForces() {return drawMass2dForces;}
    public boolean isDrawMasses2d() {return drawMasses2d;}
    public boolean isDrawMassesNumbers() {return drawMassesNumbers;}
    public boolean isDrawSpringBodyCollisions() {return drawSpringBodyCollisions;}
    public boolean isDrawSpringBodyGeomCenter() {return drawSpringBodyGeomCenter;}
    public boolean isDrawSprings2d() {return drawSprings2d;}
    public boolean isDrawSpringsNumbers() {return drawSpringsNumbers;}
    public boolean isDrawWalls2d() {return drawWalls2d;}
    public boolean isDrawWallsNumbers() {return drawWallsNumbers;}
    public boolean isDrawBorderOrientation() {return drawBorderOrientation;}
    public boolean isDrawActionFrame() {return drawActionFrame;}

    ////////////////////////////////////////////////////////////////////////////
    //                    S C E N E   D R A W A B L E S                       //
    ////////////////////////////////////////////////////////////////////////////

    public void addDrawable(SceneDrawable d) {
        drawables.add(d);
    }

    public void removeDrawable(SceneDrawable d) {
        drawables.remove(d);
    }

    public void clearDrawables() {
        drawables.clear();
    }

    public Collection<SceneDrawable> getSceneDrawablesSync() {
        return Collections.synchronizedList(drawables);
    }
}
